<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script src="http://www.google.com/jsapi?autoload={%22modules%22:[{%22name%22:%22visualization%22,%22version%22:%221%22,%22packages%22:[%22controls%22,%22charteditor%22]}]}"></script>
<script src="https://web.archive.org/web/20160324220311/http://jquery-csv.googlecode.com/git/src/jquery.csv.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script>
$(function() {
	google.load("visualization", "1", {packages:["corechart"]});

    var csv = $('#textInput').val();
    var data = $.csv.toArrays(csv, {
        onParseValue: $.csv.hooks.castToScalar
    });

    // Convert data for bar chart (summing all digits)
    var timeData = {};	// type -> table
    var funcRowMap;
    var maxDigit = 0;

    for (var i = 1; i < data.length; i++) {
    	var type = data[i][0];
   		var func = data[i][1];
      var digit = data[i][2];
   		var time = data[i][3];
   		if (timeData[type] == null) {
   			timeData[type] = [["Function", "Time (ns)"/*, { role: "style" }*/]];
        if (digit != 0)
   			  funcRowMap = {};
   		}

   		var table = timeData[type];
   		
      if (digit != 0) {
     		if (funcRowMap[func] == null)
     			funcRowMap[func] = table.push([func, 0]) - 1;
     		
     		table[funcRowMap[func]][1] += time;
      }
      else 
        table.push([func, time]);

      maxDigit = Math.max(maxDigit, digit);
    }

    // Compute average
    for (var type in timeData) {
      var table = timeData[type];
      for (var i = 1; i < table.length; i++)
        table[i][1] /= maxDigit;
    }

    // Convert data for drawing line chart per random digit
    var timeDigitData = {}; // type -> table
    var funcColumnMap;

    for (var i = 1; i < data.length; i++) {
    	var type = data[i][0];
   		var func = data[i][1];
		  var digit = data[i][2];
   		var time = data[i][3];

      if (digit == 0)
        continue;

   		if (timeDigitData[type] == null) {
   			timeDigitData[type] = [["Digit"]];
   			funcColumnMap = {};
   		}

   		var table = timeDigitData[type];

   		if (funcColumnMap[func] == null)
   			funcColumnMap[func] = table[0].push(func) - 1;

   		var row;
   		for (row = 1; row < table.length; row++)
   			if (table[row][0] == digit)
   				break;

    	if (row == table.length)
    		table.push([digit]);

		table[row][funcColumnMap[func]] = time;
	}

	for (var type in timeData) {
		$("#main").append(
      $("<a>", {name: type}),
      $("<h2>", {style: "padding-top: 70px; margin-top: -70px;"}).append(type)
    );

    $("#section").append($("<li>").append($("<a>", {href: "#" + type}).append(type)));

		drawTable(type, timeData[type]);
		drawBarChart(type, timeData[type]);
    if (timeDigitData[type] != null)
		  drawDigitChart(type, timeDigitData[type]);
	}

	$(".chart").each(function() {
		var chart = $(this);
		var d = $("#downloadDD").clone().css("display", "");
		$('li a', d).each(function() {
	        $(this).click(function() {
	            var svg = chart[0].getElementsByTagName('svg')[0].parentNode.innerHTML;
	            svg=sanitize(svg);
	            $('#imageFilename').val($("#title").html() + "_" + chart.data("filename"));
	            $('#imageGetFormTYPE').val($(this).attr('dltype'));
	            $('#imageGetFormSVG').val(svg);
	            $('#imageGetForm').submit();
	        });
	    });		
		$(this).after(d);
	});

  // Add configurations
  var thisConfig = "unknown_win64_vc2019";
  var configurations = ["corei7920@2.67_cygwin32_gcc4.8","corei7920@2.67_cygwin64_gcc4.8","corei7920@2.67_win32_vc2013","corei7920@2.67_win64_vc2013","unknown_mac32_clang7.0","unknown_mac64_clang7.0","unknown_win64_vc2019"];

  for (var i in configurations) {
    var c = configurations[i];
    $("#configuration").append($("<li>", {class : (c == thisConfig ? "active" : "")}).append($("<a>", {href: c + ".html"}).append(c)));
  }
});

function drawTable(type, timeData) {
	var data = google.visualization.arrayToDataTable(timeData);
    data.addColumn('number', 'Speedup');
    data.sort([{ column: 1, desc: true }]);
    var formatter1 = new google.visualization.NumberFormat({ fractionDigits: 3 });
    formatter1.format(data, 1);

	var div = document.createElement("div");
	div.className = "tablechart";
	$("#main").append(div);
    var table = new google.visualization.Table(div);
    redrawTable(0);
    table.setSelection([{ row: 0, column: null}]);

    function redrawTable(selectedRow) {
        // Compute relative time using the first row as basis
        var basis = data.getValue(selectedRow, 1);
        for (var rowIndex = 0; rowIndex < data.getNumberOfRows(); rowIndex++)
            data.setValue(rowIndex, 2, basis / data.getValue(rowIndex, 1));

        var formatter = new google.visualization.NumberFormat({suffix: 'x'});
        formatter.format(data, 2); // Apply formatter to second column

        table.draw(data);
    }

    google.visualization.events.addListener(table, 'select',
    function() {
        var selection = table.getSelection();
        if (selection.length > 0) {
            var item = selection[0];
            if (item.row != null)
                redrawTable(item.row);
        }
    });

}

function drawBarChart(type, timeData) {
    var defaultColors = ["#3366cc","#dc3912","#ff9900","#109618","#990099","#0099c6","#dd4477","#66aa00","#b82e2e","#316395","#994499","#22aa99","#aaaa11","#6633cc","#e67300","#8b0707","#651067","#329262","#5574a6","#3b3eac","#b77322","#16d620","#b91383","#f4359e","#9c5935","#a9c413","#2a778d","#668d1c","#bea413","#0c5922","#743411"];

	var data = google.visualization.arrayToDataTable(timeData);
	data.addColumn({ type: "string", role: "style" })
	for (var rowIndex = 0; rowIndex < data.getNumberOfRows(); rowIndex++)
		data.setValue(rowIndex, 2, defaultColors[rowIndex]);

    data.sort([{ column: 1, desc: true }]);
	var options = { 
		title: type,
		chartArea: {'width': '70%', 'height': '70%'},
		width: 800,
		height: 300,
		legend: { position: "none" },
		hAxis: { title: "Time (ns)" }
	};
	var div = document.createElement("div");
	div.className = "chart";
	$(div).data("filename", type + "_time");
	$("#main").append(div);
	var chart = new google.visualization.BarChart(div);

	chart.draw(data, options);
}

function drawDigitChart(type, timeDigitData) {
	var data = google.visualization.arrayToDataTable(timeDigitData);

	var options = { 
		title: type,
		chartArea: {'width': '70%', 'height': '80%'},
		hAxis: {
			title: "Digit",
			gridlines: { count: timeDigitData.length - 1 },
			maxAlternation: 1,
			minTextSpacing: 0
		},
		vAxis: {
			title: "Time (ns) in log scale",
			logScale: true,
			minorGridlines: { count: 10 },
      baseline: 0
		},
		width: 800,
		height: 600
	};
	var div = document.createElement("div");
	div.className = "chart";
	$(div).data("filename", type + "_timedigit");
	$("#main").append(div);
	var chart = new google.visualization.LineChart(div);

	chart.draw(data, options);
}

// http://jsfiddle.net/P6XXM/
function sanitize(svg) {
    svg = svg
        .replace(/\<svg/,'<svg xmlns="http://www.w3.org/2000/svg" version="1.1"')
        .replace(/zIndex="[^"]+"/g, '')
        .replace(/isShadow="[^"]+"/g, '')
        .replace(/symbolName="[^"]+"/g, '')
        .replace(/jQuery[0-9]+="[^"]+"/g, '')
        .replace(/isTracker="[^"]+"/g, '')
        .replace(/url\([^#]+#/g, 'url(#')
        .replace('<svg xmlns:xlink="http://www.w3.org/1999/xlink" ', '<svg ')
        .replace(/ href=/g, ' xlink:href=')
    /*.replace(/preserveAspectRatio="none">/g, 'preserveAspectRatio="none"/>')*/
    /* This fails in IE < 8
    .replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
    return s2 +'.'+ s3[0];
    })*/

    // IE specific
        .replace(/id=([^" >]+)/g, 'id="$1"')
        .replace(/class=([^" ]+)/g, 'class="$1"')
        .replace(/ transform /g, ' ')
        .replace(/:(path|rect)/g, '$1')
        .replace(/<img ([^>]*)>/gi, '<image $1 />')
        .replace(/<\/image>/g, '') // remove closing tags for images as they'll never have any content
        .replace(/<image ([^>]*)([^\/])>/gi, '<image $1$2 />') // closes image tags for firefox
        .replace(/width=(\d+)/g, 'width="$1"')
        .replace(/height=(\d+)/g, 'height="$1"')
        .replace(/hc-svg-href="/g, 'xlink:href="')
        .replace(/style="([^"]+)"/g, function (s) {
            return s.toLowerCase();
        });

    // IE9 beta bugs with innerHTML. Test again with final IE9.
    svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
        .replace(/&quot;/g, "'");
    if (svg.match(/ xmlns="/g).length == 2) {
        svg = svg.replace(/xmlns="[^"]+"/, '');
    }

    return svg;
}
</script>
<style type="text/css">
@media (min-width: 800px) {
  .container {
    max-width: 800px;
  }
}
textarea {
	font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
}
.tablechart {
	width: 700px;
	margin: auto;
	padding-top: 20px;
	padding-bottom: 20px;
}
.chart {
	padding-top: 20px;
	padding-bottom: 20px;
}
body { padding-top: 70px; }
</style>
</head>
<body>
<div class="container">
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="https://github.com/miloyip/dtoa-benchmark"><span class="glyphicon glyphicon-home"></span> dtoa-benchmark</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Configuration <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu" id="configuration">
          </ul>
        </li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Section <span class="caret"></span></a>
          <ul class="dropdown-menu" role="menu" id="section">
          </ul>
        </li>
      </ul>
      <p class="navbar-text navbar-right">Developed by <a href="https://github.com/miloyip" class="navbar-link">Milo Yip</a></p>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
<div class="page-header">
<h1 id="title">unknown_win64_vc2019</h1>
</div>
<div id="main"></div>
<h2>Source CSV</h2>
<textarea id="textInput" class="form-control" rows="5" readonly>
Type,Function,Digit,Time(ns)
randomdigit,doubleconv,1,103.422000
randomdigit,doubleconv,2,107.019000
randomdigit,doubleconv,3,119.302000
randomdigit,doubleconv,4,123.201000
randomdigit,doubleconv,5,126.719000
randomdigit,doubleconv,6,129.759000
randomdigit,doubleconv,7,137.666000
randomdigit,doubleconv,8,133.465000
randomdigit,doubleconv,9,139.259000
randomdigit,doubleconv,10,145.012000
randomdigit,doubleconv,11,155.953000
randomdigit,doubleconv,12,145.050000
randomdigit,doubleconv,13,151.716000
randomdigit,doubleconv,14,152.975000
randomdigit,doubleconv,15,160.155000
randomdigit,doubleconv,16,162.404000
randomdigit,doubleconv,17,174.070000
randomdigit,emyg,1,75.612000
randomdigit,emyg,2,81.201000
randomdigit,emyg,3,84.996000
randomdigit,emyg,4,88.791000
randomdigit,emyg,5,92.296000
randomdigit,emyg,6,95.445000
randomdigit,emyg,7,98.512000
randomdigit,emyg,8,101.385000
randomdigit,emyg,9,105.228000
randomdigit,emyg,10,108.044000
randomdigit,emyg,11,111.275000
randomdigit,emyg,12,113.399000
randomdigit,emyg,13,116.570000
randomdigit,emyg,14,115.547000
randomdigit,emyg,15,122.869000
randomdigit,emyg,16,125.364000
randomdigit,emyg,17,148.200000
randomdigit,floaxie,1,51.302000
randomdigit,floaxie,2,58.274000
randomdigit,floaxie,3,67.401000
randomdigit,floaxie,4,76.321000
randomdigit,floaxie,5,84.472000
randomdigit,floaxie,6,91.869000
randomdigit,floaxie,7,99.066000
randomdigit,floaxie,8,105.707000
randomdigit,floaxie,9,115.071000
randomdigit,floaxie,10,117.430000
randomdigit,floaxie,11,119.936000
randomdigit,floaxie,12,121.423000
randomdigit,floaxie,13,124.391000
randomdigit,floaxie,14,125.128000
randomdigit,floaxie,15,125.072000
randomdigit,floaxie,16,128.710000
randomdigit,floaxie,17,128.626000
randomdigit,fmt,1,105.266000
randomdigit,fmt,2,116.047000
randomdigit,fmt,3,124.841000
randomdigit,fmt,4,124.258000
randomdigit,fmt,5,121.815000
randomdigit,fmt,6,123.681000
randomdigit,fmt,7,132.253000
randomdigit,fmt,8,136.010000
randomdigit,fmt,9,138.022000
randomdigit,fmt,10,141.509000
randomdigit,fmt,11,145.660000
randomdigit,fmt,12,146.429000
randomdigit,fmt,13,149.514000
randomdigit,fmt,14,142.326000
randomdigit,fmt,15,148.343000
randomdigit,fmt,16,147.771000
randomdigit,fmt,17,169.117000
randomdigit,fpconv,1,135.685000
randomdigit,fpconv,2,146.550000
randomdigit,fpconv,3,159.927000
randomdigit,fpconv,4,169.214000
randomdigit,fpconv,5,176.296000
randomdigit,fpconv,6,182.490000
randomdigit,fpconv,7,188.653000
randomdigit,fpconv,8,191.473000
randomdigit,fpconv,9,196.434000
randomdigit,fpconv,10,194.403000
randomdigit,fpconv,11,199.955000
randomdigit,fpconv,12,201.495000
randomdigit,fpconv,13,197.954000
randomdigit,fpconv,14,204.596000
randomdigit,fpconv,15,214.376000
randomdigit,fpconv,16,217.430000
randomdigit,fpconv,17,220.440000
randomdigit,grisu2,1,125.406000
randomdigit,grisu2,2,136.002000
randomdigit,grisu2,3,131.690000
randomdigit,grisu2,4,131.078000
randomdigit,grisu2,5,133.324000
randomdigit,grisu2,6,136.897000
randomdigit,grisu2,7,139.207000
randomdigit,grisu2,8,142.139000
randomdigit,grisu2,9,142.853000
randomdigit,grisu2,10,149.807000
randomdigit,grisu2,11,151.105000
randomdigit,grisu2,12,155.232000
randomdigit,grisu2,13,155.774000
randomdigit,grisu2,14,159.399000
randomdigit,grisu2,15,161.156000
randomdigit,grisu2,16,164.061000
randomdigit,grisu2,17,170.995000
randomdigit,milo,1,62.613000
randomdigit,milo,2,69.110000
randomdigit,milo,3,76.748000
randomdigit,milo,4,81.638000
randomdigit,milo,5,84.303000
randomdigit,milo,6,88.055000
randomdigit,milo,7,85.880000
randomdigit,milo,8,118.707000
randomdigit,milo,9,129.551000
randomdigit,milo,10,111.460000
randomdigit,milo,11,99.181000
randomdigit,milo,12,105.637000
randomdigit,milo,13,140.935000
randomdigit,milo,14,106.934000
randomdigit,milo,15,109.047000
randomdigit,milo,16,113.420000
randomdigit,milo,17,116.652000
randomdigit,ryu,1,81.360000
randomdigit,ryu,2,83.371000
randomdigit,ryu,3,80.398000
randomdigit,ryu,4,79.152000
randomdigit,ryu,5,77.026000
randomdigit,ryu,6,74.817000
randomdigit,ryu,7,71.081000
randomdigit,ryu,8,69.037000
randomdigit,ryu,9,62.880000
randomdigit,ryu,10,66.318000
randomdigit,ryu,11,63.049000
randomdigit,ryu,12,60.845000
randomdigit,ryu,13,60.772000
randomdigit,ryu,14,58.598000
randomdigit,ryu,15,57.695000
randomdigit,ryu,16,55.896000
randomdigit,ryu,17,56.271000
randomdigit,dragonbox,1,46.012000
randomdigit,dragonbox,2,47.638000
randomdigit,dragonbox,3,46.859000
randomdigit,dragonbox,4,47.580000
randomdigit,dragonbox,5,47.257000
randomdigit,dragonbox,6,45.949000
randomdigit,dragonbox,7,45.222000
randomdigit,dragonbox,8,45.855000
randomdigit,dragonbox,9,49.689000
randomdigit,dragonbox,10,50.884000
randomdigit,dragonbox,11,49.594000
randomdigit,dragonbox,12,48.426000
randomdigit,dragonbox,13,48.294000
randomdigit,dragonbox,14,46.039000
randomdigit,dragonbox,15,47.395000
randomdigit,dragonbox,16,46.293000
randomdigit,dragonbox,17,49.234000
randomdigit,grisu_exact,1,50.867000
randomdigit,grisu_exact,2,55.277000
randomdigit,grisu_exact,3,52.392000
randomdigit,grisu_exact,4,54.517000
randomdigit,grisu_exact,5,54.037000
randomdigit,grisu_exact,6,54.194000
randomdigit,grisu_exact,7,52.027000
randomdigit,grisu_exact,8,54.234000
randomdigit,grisu_exact,9,53.911000
randomdigit,grisu_exact,10,57.632000
randomdigit,grisu_exact,11,53.070000
randomdigit,grisu_exact,12,54.807000
randomdigit,grisu_exact,13,54.739000
randomdigit,grisu_exact,14,54.875000
randomdigit,grisu_exact,15,52.611000
randomdigit,grisu_exact,16,52.384000
randomdigit,grisu_exact,17,55.250000
</textarea>
</div>
<div class="row" id="downloadDD" style="display: none">
<div class="btn-group pull-right" >
    <button class="btn dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-picture"></span></button>
    <ul class="dropdown-menu">
        <li><a tabindex="-1" href="#" dltype="image/jpeg">JPEG</a></li>
        <li><a tabindex="-1" href="#" dltype="image/png">PNG</a></li>
        <li><a tabindex="-1" href="#" dltype="application/pdf">PDF</a></li>
        <li><a tabindex="-1" href="#" dltype="image/svg+xml">SVG</a></li>
    </ul>
</div>
</div>
<form method="post" action="http://export.highcharts.com/" id="imageGetForm">
    <input type="hidden" name="filename" id="imageFilename" value="" />
    <input type="hidden" name="type" id="imageGetFormTYPE" value="" />
    <input type="hidden" name="width" value="900" />
    <input type="hidden" name="svg" value="" id="imageGetFormSVG" />
</form>
</div>
</body>
</html>